package com.ibm.cps.parsers;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import com.google.gson.JsonParser;
import com.ibm.util.ErrorCode;
import com.ibm.util.exception.CPSException;

public class ParserFactory {
	public static MessageParser getParser(InputStream inputStream)
			throws CPSException {

		ByteArrayOutputStream baos = cacheInputStream(inputStream);

		InputStream stream1 = new ByteArrayInputStream(baos.toByteArray());
		InputStream stream2 = new ByteArrayInputStream(baos.toByteArray());

		inputStream.markSupported();
		if (isXMLInput(stream1)) {
			return new XMLMessageParser();
		} else if (isJsonInput(stream2)) {
			return new JsonMessageParser();
		} else {
			throw new CPSException(ErrorCode.INVALID_INPUT_ERROR,
					"Unknown input message format.");
		}
	}

	private static ByteArrayOutputStream cacheInputStream(
			InputStream inputStream) throws CPSException {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int len;
			while ((len = inputStream.read(buffer)) > -1) {
				baos.write(buffer, 0, len);
			}
			baos.flush();
			return baos;
		} catch (Exception e) {
			throw new CPSException(ErrorCode.INTERNAL_ERROR_CODE,
					e.getMessage());
		}
	}

	private static boolean isXMLInput(InputStream inputStream) {
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			builder.parse(inputStream);
			return true;
		} catch (Exception e) {
			return false;
		} finally {
			try {
				inputStream.reset();
			} catch (IOException e) {

			}
		}
	}

	private static boolean isJsonInput(InputStream inputStream) {
		JsonParser parser = new JsonParser();
		try {
			String input = "";
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					inputStream));
			String line;
			while ((line = reader.readLine()) != null) {
				input += line;
			}
			reader.close();
			System.out.println("Input message is " + input);
			parser.parse(input);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	public static void main(String[] args) {

	}
}
